﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace MM.Common.UI.Controls
{
    public class BindingAdapter
    {
        // Fields
        private BindingContext BindingContext;
        private Dictionary<string, List<Binding>> BindingGroup = new Dictionary<string, List<Binding>>();
        private Dictionary<string, List<Control>> ControlGroup = new Dictionary<string, List<Control>>();
        private Dictionary<string, object> DataSourceDic = new Dictionary<string, object>();

        // Methods
        public BindingAdapter()
        {
            this.DefaultGroupName = "Default";
            this.DefaultPropertyName = "FieldValue";
        }

        public void Binding(string GroupName, string PropertyName, object DataSource)
        {
            this.ClearBingding(GroupName);
            List<Control> list = this.ControlGroup[GroupName];
            List<Binding> list2 = this.BindingGroup[GroupName];
            foreach (Control control in list)
            {
                list2.Add(control.DataBindings.Add(PropertyName ?? this.DefaultPropertyName, DataSource, ((IControlField)control).FieldDBName, true, DataSourceUpdateMode.OnValidation));
            }
            this.DataSourceDic[GroupName] = DataSource;
        }

        private void ClearBingding(string GroupName)
        {
            foreach (Binding binding in this.BindingGroup[GroupName])
            {
                binding.Control.DataBindings.Remove(binding);
            }
            this.BindingGroup[GroupName].Clear();
        }

        public void ClearControlsData(string GroupName)
        {
            foreach (Control control in this.ControlGroup[GroupName])
            {
                ((IControlField)control).FieldValue = null;
            }
        }

        public void EnabledControls(bool Enabled)
        {
            foreach (KeyValuePair<string, List<Control>> pair in this.ControlGroup)
            {
                foreach (Control control in pair.Value)
                {
                    foreach (Binding binding in control.DataBindings)
                    {
                        binding.ReadValue();
                    }
                    control.Enabled = Enabled;
                }
            }
        }

        public void EnabledControls(string GroupName, bool Enabled)
        {
            foreach (Control control in this.ControlGroup[GroupName])
            {
                control.Enabled = Enabled;
            }
        }

        private void FindControl(Control.ControlCollection controls, List<IControlField> IControlFieldList, List<Control> WaitSearchList)
        {
            for (int i = 0; i < controls.Count; i++)
            {
                if (controls[i] is IControlField)
                {
                    IControlFieldList.Add(controls[i] as IControlField);
                }
                else if (controls[i].Controls.Count > 0)
                {
                    WaitSearchList.Add(controls[i]);
                }
            }
        }

        public void InitAdapter(Control control)
        {
            this.BindingContext = control.BindingContext;
            List<IControlField> iControlFieldList = new List<IControlField>();
            List<Control> waitSearchList = new List<Control>();
            this.FindControl(control.Controls, iControlFieldList, waitSearchList);
            for (int i = 0; i < waitSearchList.Count; i++)
            {
                this.FindControl(waitSearchList[i].Controls, iControlFieldList, waitSearchList);
            }
            foreach (IGrouping<string, IControlField> grouping in from n in iControlFieldList
                                                                  where !string.IsNullOrEmpty(n.FieldDBName)
                                                                  group n by n.GroupName)
            {
                List<Control> list3 = new List<Control>();
                string key = grouping.Key ?? this.DefaultGroupName;
                this.ControlGroup.Add(key, list3);
                this.BindingGroup.Add(key, new List<Binding>());
                foreach (IControlField field in grouping)
                {
                    list3.Add((Control)field);
                }
            }
            iControlFieldList.Clear();
            waitSearchList.Clear();
            iControlFieldList = null;
            waitSearchList = null;
        }

        public bool IsChangeValue(string GroupName)
        {
            foreach (Control control in this.ControlGroup[GroupName])
            {
                if (((IControlField)control).isEdited)
                {
                    return true;
                }
            }
            return false;
        }

        public void ReadValue()
        {
            foreach (KeyValuePair<string, object> pair in this.DataSourceDic)
            {
                foreach (Binding binding in this.BindingContext[this.DataSourceDic[pair.Key]].Bindings)
                {
                    binding.ReadValue();
                }
            }
        }

        public void ReadValue(string GroupName)
        {
            foreach (Control control in this.ControlGroup[GroupName])
            {
                control.DataBindings[this.DefaultPropertyName].ReadValue();
            }
        }

        public void Refresh(string GroupName)
        {
            foreach (Binding binding in this.BindingGroup[GroupName])
            {
                binding.ReadValue();
            }
        }

        public void Remove(string GroupName)
        {
            this.ClearBingding(GroupName);
            this.DataSourceDic.Remove(GroupName);
        }

        public void SetControlsValue(object value)
        {
            foreach (KeyValuePair<string, List<Control>> pair in this.ControlGroup)
            {
                foreach (Control control in pair.Value)
                {
                    (control as IControlField).FieldValue = value;
                }
            }
        }

        public void SetControlsValue(string GroupName, object value)
        {
            foreach (Control control in this.ControlGroup[GroupName])
            {
                (control as IControlField).FieldValue = value;
            }
        }

        public void WriteValue()
        {
            foreach (KeyValuePair<string, List<Control>> pair in this.ControlGroup)
            {
                foreach (Control control in pair.Value)
                {
                    control.DataBindings[this.DefaultPropertyName].WriteValue();
                }
            }
        }

        public void WriteValue(string GroupName)
        {
            if (this.DataSourceDic.ContainsKey(GroupName))
            {
                foreach (Binding binding in this.BindingContext[this.DataSourceDic[GroupName]].Bindings)
                {
                    binding.WriteValue();
                }
            }
        }

        // Properties
        public string DefaultGroupName { get; set; }

        public string DefaultPropertyName { get; set; }

        public object this[string GroupName]
        {
            get
            {
                if (this.DataSourceDic.ContainsKey(GroupName))
                {
                    return this.DataSourceDic[GroupName];
                }
                return null;
            }
            set
            {
                if (value == null)
                {
                    this.Remove(GroupName);
                }
                else
                {
                    this.Binding(GroupName, this.DefaultPropertyName, value);
                }
            }
        }
    }
}
